package com.mall.seckill.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mall.order.OrderCoreService;
import com.mall.order.dto.CreateOrderRequest;
import com.mall.order.dto.CreateOrderResponse;
import com.mall.order.dto.CreateSeckillOrderRequest;
import com.mall.seckill.SeckillService;
import com.mall.seckill.converter.PromoItemConverter;
import com.mall.seckill.dal.entitys.PromoItem;
import com.mall.seckill.dal.entitys.PromoSession;
import com.mall.seckill.dal.persistence.PromoItemMapper;
import com.mall.seckill.dal.persistence.PromoSessionMapper;
import com.mall.seckill.dto.*;
import com.mall.seckill.mq.MqMessageProducer;
import com.mall.shopping.dal.entitys.Item;
import com.mall.shopping.dal.persistence.ItemMapper;
import com.mall.order.dto.CartProductDto;
import com.mall.user.dal.persistence.MemberMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.weekend.Weekend;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author lichao
 * @createdate 2021-01-29 14:23
 */
@Service
@Component
@Slf4j
public class SeckillServiceImpl implements SeckillService {
    @Autowired
    PromoSessionMapper promoSessionMapper;
    @Autowired
    PromoItemMapper promoItemMapper;
    @Autowired
    ItemMapper itemMapper;
    @Autowired
    PromoItemConverter promoItemConverter;
    @Reference(check = false,timeout = 3000)
    OrderCoreService orderCoreService;
    @Autowired
    MemberMapper memberMapper;

    @Override
    public SecKilllistResponse seckilllist(SecKilllistRequest request) {
        SecKilllistResponse response = new SecKilllistResponse();
        Example example = new Example(PromoSession.class);
        example.createCriteria().andEqualTo("sessionId",request.getSessionId());
        PromoSession promoSession = promoSessionMapper.selectOneByExample(example);
        //TODO promoSession判空
        if(promoSession == null){
            response.setSessionId(request.getSessionId());
            log.info("没有查到session{}",request.getSessionId());
            return response;
        }
        Weekend<PromoItem> weekend = new Weekend<>(PromoItem.class);
        weekend.createCriteria().andEqualTo("psId",promoSession.getSessionId());
        //TODO weekend 需要and吗？
        List<PromoItem> promoItems = promoItemMapper.selectByExample(weekend);
        List<ProductItem> productItems = promoItemConverter.promoItem2Dto(promoItems);
        for (ProductItem productItem : productItems) {

            Item item = itemMapper.selectByPrimaryKey(productItem.getId());
            productItem.setPrice(item.getPrice());
            productItem.setPicUrl(item.getImageBig());
            productItem.setProductName(item.getTitle());
        }


        response.setSessionId(promoSession.getSessionId());
        response.setPsId(promoSession.getId());
        response.setProductList(productItems);
        return response;

    }

    /**
     * 秒杀商品详情
     * @param request
     * @return
     */
    @Override
    public PromoProductDetailResponse promoProductDetail(PromoProductDetailRequest request) {

        //查询item和promoItem
        Item item = itemMapper.selectByPrimaryKey(request.getProductId());
        Example example = new Example(PromoItem.class);
        example.createCriteria().andEqualTo("itemId",request.getProductId()).
                andEqualTo("psId",request.getPsId());
        List<PromoItem> promoItems = promoItemMapper.selectByExample(example);
        PromoItem promoItem = promoItems.get(0);

        //封装dto
        PromoProductDetailDTO dto = new PromoProductDetailDTO();
        dto.setProductId(request.getProductId());
        dto.setSalePrice(item.getPrice());
        dto.setProductName(item.getTitle());
        dto.setSubTitle(item.getSellPoint());
        dto.setLimitNum(promoItem.getItemStock());
        dto.setProductImageBig(item.getImageBig());
        dto.setDetail(null);
        dto.setPromoPrice(promoItem.getSeckillPrice());
        String[] images = item.getImages();
        List<String> list = new ArrayList();
        for (String image : images) {
            list.add(image);
        }
        list.remove(0);
        dto.setProductImageSmall(list);
        PromoProductDetailResponse response = new PromoProductDetailResponse();
        response.setPromoProductDetailDTO(dto);
        return response;
    }

    /**
     * 秒杀下单
     * @param request
     * @param httpServletRequest
     * @return
     */
    @Override
    public SeckillResponse seckill(SeckillRequest request, String userInfo) {
//秒杀下单


        //  get UserId
        JSONObject object = JSON.parseObject(userInfo);
        Integer userId0 = (Integer) object.get("uid");
        Long userId = Long.valueOf(userId0);

        //get orderTotal
        Weekend<PromoItem> weekend = new Weekend<>(PromoItem.class);
        weekend.createCriteria().andEqualTo("itemId",request.getProductId()).
                andEqualTo("psId",request.getPsId());
        List<PromoItem> promoItems = promoItemMapper.selectByExample(weekend);
        PromoItem promoItem = promoItems.get(0);
        //检查秒杀库存
        if(promoItem.getItemStock()<=0 && StringUtils.isEmpty(promoItem.getItemStock())){
            SeckillResponse seckillResponse = new SeckillResponse();
            seckillResponse.setMsg("库存不足");
            seckillResponse.setCode("500");
            return seckillResponse;
        }
        //扣减秒杀库存
        promoItem.setItemStock(promoItem.getItemStock()-1);
        promoItemMapper.updateByPrimaryKey(promoItem);

        Item item = itemMapper.selectByPrimaryKey(promoItem.getItemId());
        //get cartDto
        CartProductDto cartProductDto = new CartProductDto();
        cartProductDto.setProductId(Long.valueOf(promoItem.getItemId()));
        cartProductDto.setSalePrice(promoItem.getSeckillPrice());
        cartProductDto.setProductNum(Long.valueOf(1));
        cartProductDto.setLimitNum(Long.valueOf(promoItem.getItemStock()));
        cartProductDto.setChecked("false");
        cartProductDto.setProductName(item.getTitle());
        cartProductDto.setProductImg(item.getImageBig());
        List<CartProductDto> cartProductDtos = new ArrayList<>();
        cartProductDtos.add(cartProductDto);

        //packaging createOrderRequest
        CreateOrderRequest createOrderRequest = new CreateOrderRequest();
        createOrderRequest.setUserId(userId);
        createOrderRequest.setAddressId(request.getAddressId());
        createOrderRequest.setTel(request.getTel());
        createOrderRequest.setStreetName(request.getStreetName());
        createOrderRequest.setOrderTotal(promoItem.getSeckillPrice());
        createOrderRequest.setCartProductDtoList(cartProductDtos);
        createOrderRequest.setUniqueKey("order"+System.currentTimeMillis());
        createOrderRequest.setUserName(request.getUserName());
//下单
        CreateOrderResponse order = orderCoreService.createOrder(createOrderRequest);






        SeckillResponse seckillResponse = new SeckillResponse();
        seckillResponse.setCode("200");
        return seckillResponse;
    }

    /**
     * 事务型秒杀下单
     *
     * 本地事务 ----扣库存
     * 远程事务 ----下单&生成物流信息
     * @param request
     * @param userInfo
     * @return
     */

    @Autowired
    MqMessageProducer mqMessageProducer;

    @Override
    public SeckillResponse seckillTransaction(SeckillRequest request, String userInfo) {
        //秒杀下单


        //  get UserId
        JSONObject object = JSON.parseObject(userInfo);
        Integer userId0 = (Integer) object.get("uid");
        Long userId = Long.valueOf(userId0);
        String uName = (String) object.get("uName");

        //get orderTotal
        Weekend<PromoItem> weekend = new Weekend<>(PromoItem.class);
        weekend.createCriteria().andEqualTo("itemId",request.getProductId()).
                andEqualTo("psId",request.getPsId());
        List<PromoItem> promoItems = promoItemMapper.selectByExample(weekend);
        PromoItem promoItem = promoItems.get(0);

        //发消息


        CreateSeckillOrderRequest request1 = new CreateSeckillOrderRequest();
        request1.setUserId(userId);
        request1.setUsername(request.getUserName());
        request1.setProductId(Long.valueOf(promoItem.getItemId()));
        request1.setTel(request.getTel());
        request1.setStreetName(request1.getStreetName());
        request1.setPrice(promoItem.getSeckillPrice());

        HashMap<String, Object> map = new HashMap<>();
        map.put("promoItem",promoItem);
        map.put("request",request1);
        Boolean aBoolean = mqMessageProducer.sendPromoTranactionMessage(map);

        SeckillResponse seckillResponse = new SeckillResponse();
        if(aBoolean){
            seckillResponse.setCode("200");
            seckillResponse.setMsg("success");
        }else {
            seckillResponse.setCode("500");
            seckillResponse.setMsg("fail");
        }
        return seckillResponse;
    }


}
